using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Peak.Can.Basic;
namespace WinCANTool
{
    public partial class NetNodeFind : Form
    {
        public bool SearchActive = false;
        public bool BaudRateFound = false;
        private new MDIWindow ParentForm;
        public Netparms Net = new Netparms();
        delegate void AddString(object sender, NodeFindArgs e);

        
        public NetNodeFind(MDIWindow Parent)
        {
            InitializeComponent();
            ParentForm = Parent;
            NodeTextDisplay.Clear();
            NodeTextDisplay.Text = "The following test will take a few minutes.\r\nPress \"Look for network nodes\",\r\nand" +
            " the results will be displayed.\r\n";
            NodeTextDisplay.Text += "\r\nTesting for nodes on network.\r\n\r\n";
            NodeTextDisplay.Select(0, 0);

        }

        private void StartLooking_Click(object sender, EventArgs e)
        {
            ParentForm.NodeFindResults = "";
            Net.ClientHndl = ParentForm.GetClientHandle();
            Net.NetHndl = ParentForm.GetNetHandle();
            Net.HwHndl = ParentForm.GetHwHandle();
            Net.BaudRateValues = ParentForm.GetBaudValues();
            Net.BaudRateStrings = ParentForm.GetBaudStrings();
            progressBar1.Value = 0;

            ParentForm.newMDIChild1.HaltThreadRead = true;

            Net.CurrentBaudRate = ParentForm.GetBaudrate(); 
            NodeFind NodeFinder = new NodeFind(Net);
            NodeFinder.NodeFinderEvent += new NodeFindHandler(NodeFindReady);
            Thread ThreadNodeFind = new Thread(new ThreadStart(NodeFinder.FindNodes));

            ThreadNodeFind.Start();
        }



        private void NodeFindReady(object sender, NodeFindArgs e)
        {
            if (this.NodeTextDisplay.InvokeRequired)
            {
                AddString d = new AddString(NodeFindReady);
                this.Invoke(d, new object[] { sender, e });
            }
            else
            {
                if (e.ReleaseThreadHalt)
                {
                    ParentForm.newMDIChild1.HaltThreadRead = false;
                }
                else
                {
                    NodeTextDisplay.Text += e.NodeFindString;
                    ParentForm.NodeFindResults += e.NodeDisplayString;
                    progressBar1.Value = e.Progress;
                }
            }
        }



        public void FindBaudRate()
        {

            //uint i;
            //SearchActive = true;

            ///*  Put into Listen Only Mode   */
            //CanApi2.SetHwParam(Net.HwHndl, CanApi2.PARAM_LISTEN_ONLY, 1);

            //for (i = 0; ((i < 7) && !BaudRateFound); i++)
            //{
            //    CanApi2.SetHwParam(Net.HwHndl, CanApi2.PARAM_BAUDRATE, Net.BaudRateValues[i]);
            //    CanApi2.ResetHardware(Net.HwHndl);
            //    Thread.Sleep(200);
            //}

            //SearchActive = false;
            //CanApi2.SetHwParam(Net.HwHndl, CanApi2.PARAM_LISTEN_ONLY, 0);
            

            //if ((BaudRateFound) && (i > 0))
            //{
            //    Net.CurrentBaudRate = i - 1;
            //}
        }

    
    
    
    }



    public class NodeFind
    {

        public event NodeFindHandler NodeFinderEvent;

        //int MessageCount = 0;
        uint CurrentBaud = 0;
        int ProgressVaue = 0;
        string NodeFindText="";
        uint[] BaudRates;
        string[] BaudRateText;

        /* Get handles to CAN bus */

        byte ClientHndl;
        byte NetHndl;
        byte HwHndl;
        NodeFindArgs DisplayArgs = new NodeFindArgs();

        public TPCANMsg SDOMsgOut = new TPCANMsg();
        //TPCANTimestamp Tstamp = new TPCANTimestamp();
        TPCANMsg SDOMsgIn = new TPCANMsg();

        public NodeFind(Netparms NetworkParams)
        {

            ClientHndl = NetworkParams.ClientHndl;
            NetHndl = NetworkParams.NetHndl;
            HwHndl = NetworkParams.HwHndl;
            BaudRates = NetworkParams.BaudRateValues;
            BaudRateText = NetworkParams.BaudRateStrings;
            CurrentBaud = NetworkParams.CurrentBaudRate;
           
            SDOMsgOut.DATA = new byte[8];
            DisplayArgs.ReleaseThreadHalt = false;

           // for (int k = 0; k < 10; k++)
            {
                SDOMsgIn.DATA = new byte[8];
            }

            /* Set up data for message */

            SDOMsgOut.LEN = 8;
            SDOMsgOut.DATA[0] = 0x42;
            SDOMsgOut.DATA[1] = 0x18;
            SDOMsgOut.DATA[2] = 0x10;
            SDOMsgOut.DATA[3] = 0x01;
            SDOMsgOut.DATA[4] = 0x00;
            SDOMsgOut.DATA[5] = 0x00;
            SDOMsgOut.DATA[6] = 0x00;
            SDOMsgOut.DATA[7] = 0x00;


        }



        public void FindNodes()
        {

            /* First, Use a loop to find the 
             * correct Baud rate.
             * 
             * This is done by each time,
             * Set test Baud Rate
             * send a SDO, and wait for a response.
             * When a SDO MISO is found then the 
             * correct Baud has been found.    */
 
            //for (uint i = 0; ((i < 7) & (CurrentBaud == 0)); i++)
            //{
                /*Set up correct Baud rate */
                //CanApi2.SetHwParam(HwHndl, CanApi2.PARAM_BAUDRATE, BaudRates[i]);
                //CanApi2.ResetHardware(HwHndl);

                /* Second, Loop through as specified  
                 * number of Node ID values.
                 * 
                 * For each node id:
                 * Send a expidited SDO MOSI
                 * wait a fixed period,
                 * read for any recieved messages,
                 * wait for a response.          */

                DisplayArgs.NodeFindString = ".";
                ProgressVaue += 1;
                DisplayArgs.Progress = ProgressVaue;
                DisplayNodeFind(DisplayArgs);



                for (uint nodeid = 1; nodeid < 128; nodeid++)
                {
                    ///* Setup the SDO message */

                    //SDOMsgOut.ID = 0x600 + nodeid;

                    //DisplayArgs.NodeFindString = "";
                    //ProgressVaue += 1;
                    //DisplayArgs.Progress = ProgressVaue;
                    //DisplayNodeFind(DisplayArgs);


                    ///*Send the SDO to this node id */
                    //CanApi2.Write(ClientHndl, NetHndl, ref SDOMsgOut, ref Tstamp);
                    //Thread.Sleep(10);
                    //uint result = CanApi2.Read_Multi(ClientHndl, SDOMsgIn, 3, out MessageCount);

                    //if (MessageCount != 0)
                    //{
                    //    for (int j = 0; j < MessageCount; j++)
                    //    {
                    //        if ((SDOMsgIn[j].msgbuff.ID & 0xF80) == 0x580)
                    //        {
                    //            //CurrentBaud = i;
                    //            uint FoundNodeId = SDOMsgIn[j].msgbuff.ID & 0x07F;
                    //            int vendorid = (SDOMsgIn[j].msgbuff.Data[4] + (SDOMsgIn[j].msgbuff.Data[5] * 256));
                    //            NodeFindText += "\r\nBaud Rate is: " + BaudRateText[CurrentBaud] + "\r\n";
                    //            NodeFindText += "Found node is:  " + FoundNodeId + "  (0x";
                    //            NodeFindText += FoundNodeId.ToString("X") + ")\r\n"; 
                    //            NodeFindText += "Vendor ID =  " + vendorid + "  (0x";
                    //            NodeFindText += vendorid.ToString("X") + ")\r\n";
                    //        }
                    //    }
                    //}

                }
            ProgressVaue = 890;
            DisplayArgs.Progress = ProgressVaue;
            DisplayArgs.NodeDisplayString = NodeFindText;
            DisplayArgs.NodeFindString = NodeFindText + "\r\nDone Searching";
            DisplayNodeFind(DisplayArgs);
            DisplayArgs.ReleaseThreadHalt = true;
            DisplayNodeFind(DisplayArgs);
           

        }


        protected virtual void DisplayNodeFind(NodeFindArgs e)
        {

            if (NodeFinderEvent != null)
                NodeFinderEvent(this, e);
        }



    }



}
